package xin.nick.minicat;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.*;

/**
 * @author Nick
 * @date 2021/6/20
 * @description
 */
public class MiniCatBootstrap {


    private Map<String, Servlet> servletObjectMap = new HashMap<String, Servlet>();

    private MiniCatContent miniCatContent;
    /**
     * 初始化,启动操作
     */
    public void start() throws Exception {

        // miniCatContent 创建 Context
        miniCatContent = new MiniCatContent();

        // 加载解析 server.xml
        loadServlet();

        // 注册启动RequestProcess;
        new RequestProcess(miniCatContent).init();
    }


    private void loadServlet() throws Exception {

        // 扫描指定目录下面的文件夹 默认为"./server.xml"
        InputStream resourceInputStream = this.getClass().getClassLoader()
                .getResourceAsStream("server.xml");

        // 拿到端口号等数据
        if(Objects.nonNull(resourceInputStream)) {
            SAXReader saxReader = new SAXReader();
            Document document = saxReader.read(resourceInputStream);
            Element rootElement = document.getRootElement();
            // 这里应该需要扫描多个的,目前指定扫描一个
            Element connectorElement = (Element) rootElement.selectSingleNode("/Server/Service/Connector");
            if(Objects.nonNull(connectorElement)) {
                String port = connectorElement.attributeValue("port");
                if(Objects.nonNull(port) && port.trim().length() > 0) {
                    miniCatContent.setPort(Integer.valueOf(port));
                }
            }

            Element hostElement = (Element) rootElement.selectSingleNode("/Server/Service/Engine/Host");
            if(Objects.nonNull(hostElement)) {
                String appBase = hostElement.attributeValue("appBase");
                if(Objects.nonNull(appBase) && appBase.trim().length() > 0) {
                    miniCatContent.setAppBase(appBase);
                }
            }
        }

        // 根据文件夹创建相对应的配置文件
        String appBase = miniCatContent.getAppBase();
        if(Objects.isNull(appBase) || appBase.trim().length() == 0) {
            appBase = StaticResourceUtil.getAbsolutePath("") + File.separator + "webapps";
            miniCatContent.setAppBase(appBase);
        }

        List<String> projectList = new ArrayList<>();
        File appBaseFile = new File(appBase);
        if(appBaseFile.exists()) {
            File[] projectFiles = appBaseFile.listFiles();
            // 根据文件名扫描相对应的web.xml,完善配置文件
            for(File file : projectFiles) {
                if(file.isDirectory()) {
                    String path = file.getAbsolutePath();
                    int startIndex = path.indexOf(appBase);
                    projectList.add(path.substring(startIndex + appBase.length() + 1));
                    String xmlPath = file.getPath() + File.separator + "web.xml";
                    loadProjectServlet(file.getName(),xmlPath);
                }
            }
            miniCatContent.setProjectList(projectList);

        }

    }

    private void loadProjectServlet(String projectName, String xmlPath) throws DocumentException, ClassNotFoundException, IllegalAccessException, InstantiationException, FileNotFoundException {

        // 拿到 项目-配置文件 map 进行初始化
        Map<String, MiniCatConfiguration> projectCatConfigurationMap = miniCatContent.getProjectConfigurationMap();
        MiniCatConfiguration miniCatConfiguration = new MiniCatConfiguration();
        miniCatConfiguration.setProjectName(projectName);
        projectCatConfigurationMap.put(projectName,miniCatConfiguration);

        // 初始化 url-Servlet map, url - ServletClassName
        Map<String, String> servletClassNameMap = new HashMap<>();
        Map<String, Servlet> servletObjectMap = new HashMap<>();
        miniCatConfiguration.setServletClassNameMap(servletClassNameMap);
        miniCatConfiguration.setServletObjectMap(servletObjectMap);

        // 没有web.xml文件就直接返回
        if(!new File(xmlPath).exists()) {
            return;
        }

        InputStream resourceInputStream = new FileInputStream(xmlPath);
        SAXReader saxReader = new SAXReader();

        Document document = saxReader.read(resourceInputStream);
        Element rootElement = document.getRootElement();

        List<Element> selectNodes = rootElement.selectNodes("//servlet");
        for(Element element : selectNodes) {

            // servlet名字
            Element servletNameElement = (Element) element.selectSingleNode("servlet-name");
            String servletName = servletNameElement.getStringValue();

            // servlet加载的类
            Element servletClassElement = (Element) element.selectSingleNode("servlet-calss");
            String servletClass = servletClassElement.getStringValue();

            // 根据servlet-name的值找到url-pattern
            Element servletMapping = (Element) rootElement.selectSingleNode("/web-app/servlet-mapping[servlet-name='" + servletName + "']");
            //
            String urlPattern = servletMapping.selectSingleNode("url-pattern").getStringValue();

            HttpServlet httpServlet = (HttpServlet) Class.forName(servletClass).newInstance();

            //  根据 startup-run 来设置 容器启动时初始化
            //            httpServlet.init();
            servletClassNameMap.put(urlPattern, servletClass);
            servletObjectMap.put(urlPattern, httpServlet);
        }

        // 准备解析欢迎页面
//        Element indexElement = (Element) rootElement.selectSingleNode("/web-app/index-file");


    }

}
